package dao

import (
	"haiqiu-go-admin/entity"
	"haiqiu-go-admin/entity/dto"
	"haiqiu-go-admin/utils"
	"log"
	"strconv"
	"strings"
)

// 根据ID查询数据
func UserById(id int64) (entity.SysUser, error) {
	row := DB.QueryRow("select `id`, `dept_id`, `username`, `nickname`, `password`, "+
		"`email`, `phone`, `sex`, `avatar`, `login_time`, `login_ip`, `login_location`, "+
		"`sort`, `active`, `remark`, `del`, `create_time`, `update_time` "+
		"from sys_user where id = ?", id)
	var sysUser entity.SysUser
	err := row.Scan(
		&sysUser.Id,
		&sysUser.DeptId,
		&sysUser.Username,
		&sysUser.Nickname,
		&sysUser.Password,
		&sysUser.Email,
		&sysUser.Phone,
		&sysUser.Sex,
		&sysUser.Avatar,
		&sysUser.LoginTime,
		&sysUser.LoginIp,
		&sysUser.LoginLocation,
		&sysUser.Sort,
		&sysUser.Active,
		&sysUser.Remark,
		&sysUser.Del,
		&sysUser.CreateTime,
		&sysUser.UpdateTime,
	)
	if err != nil {
		panic(err)
	}
	return sysUser, nil
}

// 根据用户名查询数据
func SelectUserByUserName(username string) (*entity.SysUser, error) {
	row := DB.QueryRow("select `id`, `dept_id`, `username`, `nickname`, `password`, "+
		"`email`, `phone`, `sex`, `avatar`, `login_time`, `login_ip`, `login_location`, "+
		"`sort`, `active`, `remark`, `del`, `create_time`, `update_time` "+
		"from sys_user where username = ?", username)
	var sysUser entity.SysUser
	err := row.Scan(
		&sysUser.Id,
		&sysUser.DeptId,
		&sysUser.Username,
		&sysUser.Nickname,
		&sysUser.Password,
		&sysUser.Email,
		&sysUser.Phone,
		&sysUser.Sex,
		&sysUser.Avatar,
		&sysUser.LoginTime,
		&sysUser.LoginIp,
		&sysUser.LoginLocation,
		&sysUser.Sort,
		&sysUser.Active,
		&sysUser.Remark,
		&sysUser.Del,
		&sysUser.CreateTime,
		&sysUser.UpdateTime,
	)
	if err != nil {
		return nil, err
	}
	return &sysUser, nil
}

// 分页查询总条数
func UserPageCount(page dto.UserQueryDto) (count int64, err error) {
	query := getCondition(page, true)
	err = DB.QueryRow(query.GetSql(), query.GetVal()...).Scan(&count)
	if err != nil {
		log.Println(err.Error())
		return 0, err
	}
	return count, nil
}

// 分页查询数据
func UserPageList(page dto.UserQueryDto) (*[]entity.SysUser, error) {
	query := getCondition(page, false)
	rows, err := DB.Query(query.GetSql(), query.GetVal()...)
	if err != nil {
		log.Println(err.Error())
		return nil, err
	}
	var sysUsers []entity.SysUser
	for rows.Next() {
		var sysUser = entity.SysUser{}
		err := rows.Scan(
			&sysUser.Id,
			&sysUser.DeptId,
			&sysUser.Username,
			&sysUser.Nickname,
			&sysUser.Password,
			&sysUser.Email,
			&sysUser.Phone,
			&sysUser.Sex,
			&sysUser.Avatar,
			&sysUser.LoginTime,
			&sysUser.LoginIp,
			&sysUser.LoginLocation,
			&sysUser.Sort,
			&sysUser.Active,
			&sysUser.Remark,
			&sysUser.Del,
			&sysUser.CreateTime,
			&sysUser.UpdateTime,
		)
		if err != nil {
			log.Println(err.Error())
			return nil, err
		}
		sysUsers = append(sysUsers, sysUser)
	}
	return &sysUsers, nil
}

// 获取条件查询语句
func getCondition(page dto.UserQueryDto, count bool) *utils.Wrapper {
	query := utils.QueryWrapper()
	if count {
		query.Count("sys_user")
	} else {
		query.Page("sys_user", page.PageIndex, page.PageSize)
	}
	if page.Params.Active != nil {
		query.Eq("active", *page.Params.Active)
	}
	if page.Params.BeginTime != nil && page.Params.EndTime != nil {
		query.Between("login_time", *page.Params.BeginTime,
			*page.Params.EndTime)
	}
	if page.Params.Phone != nil {
		query.Like("phone", *page.Params.Phone)
	}
	if page.Params.Username != nil {
		query.Like("username", *page.Params.Username)
	}
	if page.Params.DeptId != nil {
		query.Like("dept_id", *page.Params.DeptId)
	}
	//query.EqCondition(page.Params.Active != nil, "active", page.Params.Active).
	//	BetweenCondition(page.Params.BeginTime != nil && page.Params.EndTime != nil,
	//		"login_time", page.Params.BeginTime,
	//		page.Params.EndTime).
	//	LikeCondition(page.Params.Phone != nil, "phone", page.Params.Phone).
	//	LikeCondition(page.Params.Username != nil, "username", page.Params.Username)
	return query
}

// 新增数据
func UserAdd(sysUser *entity.SysUser) (int64, error) {
	exec, err := DB.Exec("INSERT INTO `sys_user` "+
		"(`id`, `dept_id`, `username`, `nickname`, `password`, `email`, `phone`, "+
		"`sex`, `avatar`, `login_time`, `login_ip`, `login_location`, `sort`, "+
		"`active`, `remark`, `del`, `create_time`, `update_time`) VALUES "+
		"(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
		&sysUser.Id,
		&sysUser.DeptId,
		&sysUser.Username,
		&sysUser.Nickname,
		&sysUser.Password,
		&sysUser.Email,
		&sysUser.Phone,
		&sysUser.Sex,
		&sysUser.Avatar,
		&sysUser.LoginTime,
		&sysUser.LoginIp,
		&sysUser.LoginLocation,
		&sysUser.Sort,
		&sysUser.Active,
		&sysUser.Remark,
		&sysUser.Del,
		&sysUser.CreateTime,
		&sysUser.UpdateTime,
	)
	if err != nil {
		return 0, err
	}
	lastInsertId, err := exec.LastInsertId()
	if err != nil {
		return 0, err
	}
	return lastInsertId, nil
}

// 根据ID更新数据
func UserUpdate(sysUser *entity.SysUser) (int64, error) {
	exec, err := DB.Exec("update `sys_user` set "+
		"`dept_id` = ?, `username` = ?, `nickname` = ?, "+
		"`email` = ?, `phone` = ?, `sex` = ?, `avatar` = ?, `login_time` = ?, "+
		"`login_ip` = ?, `login_location` = ?, `sort` = ?, `active` = ?, `remark` = ?, "+
		"`del` = ?, `create_time` = ?, `update_time` = ? where `id` = ?",
		&sysUser.DeptId,
		&sysUser.Username,
		&sysUser.Nickname,
		&sysUser.Email,
		&sysUser.Phone,
		&sysUser.Sex,
		&sysUser.Avatar,
		&sysUser.LoginTime,
		&sysUser.LoginIp,
		&sysUser.LoginLocation,
		&sysUser.Sort,
		&sysUser.Active,
		&sysUser.Remark,
		&sysUser.Del,
		&sysUser.CreateTime,
		&sysUser.UpdateTime,
		&sysUser.Id,
	)
	if err != nil {
		return 0, err
	}
	lastInsertId, err := exec.LastInsertId()
	if err != nil {
		return 0, err
	}
	return lastInsertId, nil
}

// 根据ID删除数据
func UserDelete(id int64) (int64, error) {
	exec, err := DB.Exec("delete from sys_user where id = ?")
	if err != nil {
		panic(err)
		return 0, err
	}
	rowsAffected, err := exec.RowsAffected()
	if err != nil {
		panic(err)
		return 0, err
	}
	return rowsAffected, nil
}

func UserDeleteBatch(ids []int64) (int64, error) {
	var idsStr string
	for index, id := range ids {
		if index == len(ids)-1 {
			idsStr += strconv.FormatInt(id, 10)
		} else {
			idsStr += strconv.FormatInt(id, 10) + ", "
		}
	}
	exec, err := DB.Exec("delete from sys_user where id in (?)", idsStr)
	if err != nil {
		panic(err)
		return 0, err
	}
	rowsAffected, err := exec.RowsAffected()
	if err != nil {
		panic(err)
		return 0, err
	}
	return rowsAffected, nil
}

// 查询所有数据
func UserList() (*[]entity.SysUser, error) {
	rows, err := DB.Query("select * from sys_user")
	if err != nil {
		panic(err)
		return nil, err
	}
	var sysUsers []entity.SysUser
	for rows.Next() {
		var sysUser entity.SysUser
		err := rows.Scan(
			&sysUser.Id,
			&sysUser.DeptId,
			&sysUser.Username,
			&sysUser.Nickname,
			&sysUser.Password,
			&sysUser.Email,
			&sysUser.Phone,
			&sysUser.Sex,
			&sysUser.Avatar,
			&sysUser.LoginTime,
			&sysUser.LoginIp,
			&sysUser.LoginLocation,
			&sysUser.Sort,
			&sysUser.Active,
			&sysUser.Remark,
			&sysUser.Del,
			&sysUser.CreateTime,
			&sysUser.UpdateTime,
		)
		if err != nil {
			panic(err)
			return nil, err
		}
		sysUsers = append(sysUsers, sysUser)
	}
	return &sysUsers, nil
}

func ActiveUserById(userId int64, active *bool) (any, error) {
	exec, err := DB.Exec("update sys_user set active = ? where id = ?", active, userId)
	if err != nil {
		panic(err)
		return nil, err
	}
	rowsAffected, err := exec.RowsAffected()
	if err != nil {
		panic(err)
		return nil, err
	}
	return rowsAffected, nil
}

func ResetPwd(userId int64, newPassword string) (any, error) {
	exec, err := DB.Exec("update sys_user set password = ? where id = ?", newPassword, userId)
	if err != nil {
		panic(err)
		return nil, err
	}
	rowsAffected, err := exec.RowsAffected()
	if err != nil {
		panic(err)
		return nil, err
	}
	return rowsAffected, nil
}

func UserAddByRoleId(roleId int64, userIds []int64) (int64, error) {
	var sqls strings.Builder
	sqls.WriteString("insert into `sys_user_role` (`user_id`,`role_id`) values ")
	var values []any
	for index, userId := range userIds {
		if index == len(userIds)-1 {
			sqls.WriteString("(?, ?) ")
		} else {
			sqls.WriteString("(?, ?), ")
		}
		values = append(values, userId, roleId)
	}
	s := sqls.String()
	exec, err := DB.Exec(s, values...)
	if err != nil {
		panic(err)
		return 0, err
	}
	rowsAffected, err := exec.RowsAffected()
	if err != nil {
		panic(err)
		return 0, err
	}
	return rowsAffected, nil
}

func UserRemoveByRoleId(roleId int64, userIds []int64) (int64, error) {
	var ids []any
	ids = append(ids, roleId)
	var params = "delete from `sys_user_role` where role_id = ? and user_id in ( "
	for index, id := range userIds {
		ids = append(ids, id)
		if index != len(userIds)-1 {
			params += "?, "
		} else {
			params += "? "
		}
	}
	params += ")"
	exec, err := DB.Exec(params, ids...)
	if err != nil {
		log.Println(err.Error())
		return 0, err
	}
	rowsAffected, err := exec.RowsAffected()
	if err != nil {
		log.Println(err.Error())
		return 0, err
	}
	return rowsAffected, nil
}
